package com.wdb007.venus.wss.channelgroup;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.ChannelGroupFuture;
import io.netty.channel.group.ChannelMatcher;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

public class BookCaseChannelGroups {

	public static Logger logger = LoggerFactory.getLogger(BookCaseChannelGroups.class);
	
	private static final ChannelGroup BOOKCASE_CHANNEL_GROUP = new DefaultChannelGroup("bookcaseChannelGroup", GlobalEventExecutor.INSTANCE);
	
	private static final Map<String, ChannelGroup> BOOKCASE_MAP = new ConcurrentHashMap<String, ChannelGroup>();
	
	private static final Map<Channel, String> BOOKCASE_CHANNEL_MAP = new ConcurrentHashMap<Channel, String>();
	
	private static final Map<String, Channel> BOOKCASE_CHANNEL = new ConcurrentHashMap<String, Channel>();
	
	public static void add(String bookcaseId, Channel channel) {
		logger.info("addChannel===== bookcaseId: [{}], channel: [{}]", bookcaseId, channel);
		BOOKCASE_CHANNEL_GROUP.add(channel);
		BOOKCASE_CHANNEL_MAP.put(channel, bookcaseId);
		BOOKCASE_CHANNEL.put(bookcaseId, channel);
		if(BOOKCASE_MAP.containsKey(bookcaseId)) {
			BOOKCASE_MAP.get(bookcaseId).add(channel);
		}else{
			ChannelGroup channelGroup = new DefaultChannelGroup(bookcaseId, GlobalEventExecutor.INSTANCE);
			channelGroup.add(channel);
			BOOKCASE_MAP.put(bookcaseId, channelGroup);
		}
	}
	
	public static ChannelGroupFuture broadcast(String bookcaseId, Object msg) {
		if(BOOKCASE_CHANNEL.get(bookcaseId) != null) {
			logger.info("broadcast==== bookcaseId: [{}], msg: [{}]", bookcaseId, msg);
			BOOKCASE_CHANNEL.get(bookcaseId).writeAndFlush(new TextWebSocketFrame((String)msg));
		}
		
//		if(BOOKCASE_MAP.get(bookcaseId) != null) 
//			return BOOKCASE_MAP.get(bookcaseId).writeAndFlush(new TextWebSocketFrame((String)msg));
		return null;
	}
	
	public static ChannelGroupFuture broadcast(String bookcaseId, Object msg, ChannelMatcher matcher) {
//		if(BOOKCASE_MAP.get(bookcaseId) != null) 
//			return BOOKCASE_MAP.get(bookcaseId).writeAndFlush(new TextWebSocketFrame((String)msg), matcher);
		if(BOOKCASE_CHANNEL.get(bookcaseId) != null)
			 BOOKCASE_CHANNEL.get(bookcaseId).writeAndFlush(new TextWebSocketFrame((String)msg));
		return null;
	}
	
	public static ChannelGroup flush(String bookcaseId) {
		return BOOKCASE_MAP.get(bookcaseId).flush();
	}
	
	public static boolean discard(Channel channel) {
		logger.info("discardChannel===== channel: [{}]", channel);
		String bookcaseId = BOOKCASE_CHANNEL_MAP.remove(channel);
		BOOKCASE_MAP.get(bookcaseId).remove(channel);
		BOOKCASE_CHANNEL.remove(bookcaseId);
		return BOOKCASE_CHANNEL_GROUP.remove(channel);
	}
	
	public static boolean discard(String bookcaseId, Channel channel) {
		BOOKCASE_CHANNEL_MAP.remove(channel);
		BOOKCASE_MAP.get(bookcaseId).remove(channel);
		BOOKCASE_CHANNEL.remove(bookcaseId);
		return BOOKCASE_CHANNEL_GROUP.remove(channel);
	}
	
	public static ChannelGroupFuture disconnect() {
		return BOOKCASE_CHANNEL_GROUP.disconnect();
	}
	
	public static ChannelGroupFuture disconnect(String bookcaseId) {
		return BOOKCASE_MAP.get(bookcaseId).disconnect();
	}
	
	public static ChannelGroupFuture disconnect(ChannelMatcher matcher) {
		return BOOKCASE_CHANNEL_GROUP.disconnect(matcher);
	}
	
	public static ChannelGroupFuture disconnect(String bookcaseId, ChannelMatcher matcher) {
		return BOOKCASE_MAP.get(bookcaseId).disconnect(matcher);
	}
	
	public static boolean contains(Channel channel) {
		return BOOKCASE_CHANNEL_GROUP.contains(channel);
	}
	
	public static String getBookCaseId(Channel channel) {
		return BOOKCASE_CHANNEL_MAP.get(channel);
	}
}
